/*
 * datetime.c
 *
 *  Created on: Dec 3, 2012
 *      Author: Home
 */

#include "datetime.h"
/* Define */
#define bool _Bool
#define FALSE 0
#define TRUE !FALSE
#define YEAR0           1900            /* the first year */
#define EPOCH_YR        1970            /* EPOCH = Jan 1 1970 00:00:00 */
#define SECS_DAY        (24L * 60L * 60L)
#define LEAPYEAR(year)  (!((year) % 4) && (((year) % 100) || !((year) % 400)))
#define YEARSIZE(year)  (LEAPYEAR(year) ? 366 : 365)
#define FIRSTSUNDAY(timp)       (((timp)->tm_yday - (timp)->tm_wday + 420) % 7)
#define FIRSTDAYOF(timp)        (((timp)->tm_wday - (timp)->tm_yday + 420) % 7)
#define TIME_MAX        ULONG_MAX
#define ABB_LEN         3

#define	EPOCH_STRING	17

const int _ytab[2][12] = {
        { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
        { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
};

const int mon_days [] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};


void dec_to_string(char *datas, uint8_t var) {

	datas[0] = var/10;
	var = var - datas[0]*10;
	datas[1] = var;

	datas[0]+=48;
	datas[1]+=48;
}
/*
 * Converts a 32bit epoch time to a comma separated string dd/mm/yyyy,HH:MM,
 */
void epoch_to_string (uint32_t time, char *epochString){
	epochTimeTypeDef datetime;
	uint8_t datas[2];

	epoch_to_time(time, &datetime);
	dec_to_string(datas,datetime.tm_mday);
	epochString[0]=datas[0];
	epochString[1]=datas[1];
	epochString[2]='/';
	dec_to_string(datas,datetime.tm_mon+1);
	epochString[3]=datas[0];
	epochString[4]=datas[1];
	epochString[5]='/';
	dec_to_string(datas,datetime.tm_year+YEAR0-2000);
	epochString[6]='2';
	epochString[7]='0';
	epochString[8]=datas[0];
	epochString[9]=datas[1];
	epochString[10]=',';
	dec_to_string(datas,datetime.tm_hour);
	epochString[11]=datas[0];
	epochString[12]=datas[1];
	epochString[13]=':';
	dec_to_string(datas,datetime.tm_min);
	epochString[14]=datas[0];
	epochString[15]=datas[1];
}

void epoch_to_time(uint32_t time, epochTimeTypeDef *timep) {
	uint32_t dayclock, dayno;
    int year = EPOCH_YR;

    dayclock = (unsigned long)time % SECS_DAY;
    dayno = (unsigned long)time / SECS_DAY;

    timep->tm_sec = dayclock % 60;
    timep->tm_min = (dayclock % 3600) / 60;
    timep->tm_hour = dayclock / 3600;
    timep->tm_wday = (dayno + 4) % 7;       /* day 0 was a thursday */
    while (dayno >= YEARSIZE(year)) {
            dayno -= YEARSIZE(year);
            year++;
    }
    timep->tm_year = year - YEAR0;
    timep->tm_yday = dayno;
    timep->tm_mon = 0;
    while (dayno >= _ytab[LEAPYEAR(year)][timep->tm_mon]) {
            dayno -= _ytab[LEAPYEAR(year)][timep->tm_mon];
            timep->tm_mon++;
    }
    timep->tm_mday = dayno + 1;
    timep->tm_isdst = 0;
}

uint32_t time_to_epoch (epochTimeTypeDef *ltm) {
   long tyears, tdays, leaps, utc_hrs;
   int i;

   tyears = (ltm->tm_year)-70; // tm->tm_year is from 1900.
   leaps = (tyears + 2) / 4; // no of next two lines until year 2100.
   tdays = 0;
   for (i=0; i < ltm->tm_mon; i++) tdays += mon_days[i];

   tdays += ltm->tm_mday-1; // days of month passed.
   tdays = tdays + (tyears * 365) + leaps;

   utc_hrs = ltm->tm_hour;
   return (tdays * 86400) + (utc_hrs * 3600) + (ltm->tm_min * 60) + ltm->tm_sec;
}
